#ifndef xpack_lang_cxx_strcat
#define xpack_lang_cxx_strcat
#pragma push_macro("xuser")
#undef  xuser
#define xuser mixc::lang_cxx::inc
#include"define/base_type.hpp"
#include"lang/cxx.hpp"
#include"macro/xforward.hpp"
#include"macro/xunlikely.hpp"
#pragma pop_macro("xuser")

namespace mixc::lang_cxx{
    template<class item_t, class the_t = cxx<item_t>>
    inline void strcat_core(auto const & self, auto const & list, auto const & alloc) {
        auto total_length   = uxx(self->length);
        auto length         = uxx(list->length);
        auto i              = uxx{};

        for(; i < length; i++){
            total_length   += list[i]->length;
        }

        auto stream         = alloc(total_length);
        xunlikely(stream == nullptr){
            return;
        }

        stream.output((item_t *)self, self->length);
        
        for(uxx i = 0; i < length; i++){
            auto curr       = list[i];
            stream.output((item_t *)curr, curr->length);
        }
    }

    template<class item_t>
    template<class seq_t, class, class, class xalloc_t, class ret_t, class>
    inline ret_t cxx<item_t>::strcat(seq_t && values, xalloc_t const & alloc) const {
        auto seqx           = inc::unified_seq<seq_t>(xforward(values));
        auto result         = the_t{};
        auto allocx         = the_t::helper::stream_helper(alloc, xmodify(result.m_ptr), xmodify(result.m_length));
        strcat_core<item_t>(xthe, seqx, allocx);

        if constexpr (inc::is_same<the_t, ret_t>){
            return result;
        }
    }

    template<class item_t>
    template<class xalloc_t, class ret_t, class>
    inline ret_t cxx<item_t>::strcat(the_cref_t value, xalloc_t const & alloc) const {
        return xthe.strcat({ value }, alloc);
    }
}

#endif
